home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / program / oxcc1434.zip / DOC / CFF.TXT < prev    next >
Text File  |  1996-09-03  |  68KB  |  2,000 lines

  1.  
  2.                      Culvers Fabulous Filesystem
  3.                             Version 5.9
  4.                            June 15, 1995
  5.  
  6.               Copyright 1991, 1992, 1993, 1994, 1995 Norman D. Culver
  7.                           All Rights Reserved
  8.  
  9.  
  10.                     Send bug reports and suggestions to:
  11.                             Oxbow Software
  12.                        1323 S.E. 17th Street #662
  13.                         Ft. Lauderdale, FL 33316
  14.                             (954) 463-4754
  15.                             ndc@icanect.net
  16.  
  17.  
  18.         This software package is distributed as a preliminary version for
  19.                 TESTING PURPOSES ONLY, WITHOUT ANY WARRANTY;
  20.                    without even the implied warranty of
  21.             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  22.  
  23.  
  24.  
  25. GENERAL DESCRIPTION
  26.  
  27. This distribution contains a single threaded 32 bit portable library
  28. compiled with gcc for the Intel 386 cpu. The library contains external
  29. references to functions in 'cfport.c' which is supplied as source code.
  30. The user can modify cfport.c to accommodate a non-unix like OS.
  31.  
  32. The user API for the library is declared in the file 'cff.h' and described
  33. in this document. CFF is a filesystem/database engine which handles
  34. allocation of memory, extended memory and disk. It supports incrementally
  35. hashed and B+ tree storage maps in an identical fashion for memory and
  36. disk. The standard flavors of malloc are included. NEW for the first time,
  37. to my knowledge, is the ability to malloc by category and the ability
  38. to malloc PERMANENTLY.
  39.  
  40. Data is stored in and accessed through 'objects' which are referenced
  41. in the classical filesystem manner. e.g. MEMORY/myobject/subobject/...
  42. Objects are opened and closed in the time honored unix fashion. But there
  43. is a big difference between CFF objects and normal filesystem objects.
  44. Each object has the properties of a directory, stack, file, dictionary and
  45. repository. Objects can be created as F_SORTED, in which case they are
  46. B+ trees, and/or with their own local 'bitmaps' for locality of reference,
  47. or, if hashed, with PREALLOCATED DATA AND ENTRIES for ultra fast inserts.
  48. The objects expand and shrink automatically as entries are added or deleted.
  49. The in-core index for hashed objects is never saved to disk because it can be
  50. rebuilt when the object is loaded. Data can be accessed directly in the
  51. localizer buffers or copied to/from user space.
  52.  
  53.  
  54. COPY OBJECTS
  55.  
  56. The 'cfcopy' command will move an object and all subobjects within and
  57. between filesystems. A filesystem on disk is denoted with the extension
  58. '.cff'.     The filesystems for memory and extended memory
  59. (if it exists) are predefined as MEMORY and EXTDMEM. The copy command
  60. will create a filesystem on disk if an object is copied to a '.cff' object.
  61.  
  62. The command: 
  63.  
  64.     cfcopy("newsys.cff", "MEMORY/object/subobject/target");
  65.  
  66. copies the object named 'target' to the disk file newsys.cff and thus
  67. 'target' becomes a filesystem. Conversely, filesystems can become objects, etc.
  68.  
  69.  
  70. PATHNAME TRANSLATION
  71.  
  72. A pathname translation facility permits brevity.
  73. Translation dictionaries are maintained for process, application and system.
  74.  
  75. Example:
  76.  
  77. void *h1, *h2;
  78.  
  79.      cfdef("phone book", "myfile.cff/users/applications/faxmodem/phones");
  80.      h1 = cfopen("phone book", F_RDWR, NULL);
  81. or
  82.      h2 = cfcopy("MEMORY/tempobj", "phone book");
  83.      
  84. or
  85.      h2 = cfcopy("MEMORY/tempobj", h1);
  86.  
  87. And when finished you can get a fully garbage collected and shrunk disk object 
  88. with the command:
  89.  
  90.  
  91.     cfcopy(h1, h2);
  92. or
  93.     cfcopy("phone book", h2);
  94. or
  95.     cfcopy("phone book", "MEMORY/tempobj");
  96.  
  97.  
  98. EXTERNAL FILES
  99.  
  100. It is possible to access normal OS files and directories. If a path doesn't
  101. reference a .cff filesystem then it is assumed to be external. Copy to/from an
  102. external file only exercises the file property of an object, so it is
  103. trivial to import/export external data.
  104.  
  105.  
  106. FANCY MALLOCS
  107.  
  108. The CFF library supplies standard versions of malloc, calloc, realloc etc.
  109. which MUST superceed the standard compiler versions. Don't worry, these
  110. implementations are fast and debugged. They are implemented with skip lists
  111. and keep their bookeeping info separate from the allocated data. This can
  112. increase the speed in a demand paged environment by a large factor.
  113.  
  114. The enhancements to malloc are simple to use but rather complicated to
  115. implement. They permit the programmer to malloc, calloc, free etc. by
  116. CATEGORY and they are FAST. Category 0 is reserved for normal malloc, and
  117. is somewhat segregated in the address space because it calls 'sbrk()'
  118. directly. All other categories call cfmalloc() which does it's own calls
  119. to sbrk (actually PORTSBRK in cfport.c). NOTE: Normal malloc, etc. will work
  120. even if cfinit() is not issued.
  121.  
  122. Examples:
  123.  
  124. void *ptr;
  125.  
  126.     ptr = mallocC (5, 1024);  // malloc 1K bytes for category 5
  127.     freeC (5, ptr);           // free the pointer in category 5
  128.     freecat (5);              // free all memory allocated to category 5
  129.  
  130. Permanent categories have negative numbers.
  131.  
  132.    NOTE -- VERSION 5.9 HAS DISABLED PERMANENT CATEGORIES
  133.    DUE TO THE VARIABILITY IN SUPPORTING OPERATING SYSTEMS
  134.    FOR ANY GIVEN COMPATIBLE SET OF OPERATING SYSTEMS, THEY
  135.    CAN EASILY BE RE-ENABLED.
  136.  
  137.     ptr = malloc (-20, 1024);  // malloc 1K bytes for permanent category -20
  138.     freeC (-20, ptr);          // free the pointer in category -20
  139.     freecat (-20);             // free all memory allocated to category -20
  140.  
  141.  
  142. Permanent categories are enabled only if the programmer has named a
  143. filesystem when 'cfinit' is called.
  144.  
  145. main()
  146. {
  147. cfinit("app1", 512, "myfile.cff"); // enables permanent categories in myfile.cff
  148. or
  149. cfinit("app1", 512, NULL);         // permanent categories are disabled;
  150.  
  151. ...
  152.  
  153. cfexit(); // saves active permanent categories and closes objects
  154.           // cfinit calls atexit with this function, you do not
  155.           // have to include it in the program, but it is harmless to do
  156.           // so.
  157. }
  158.  
  159. Data in active permanent categories is reloaded to exactly the same memory
  160. addresses at program startup and saved in the named filesystem at program exit.
  161. Creep in the data segment as program development proceeds is accommodated
  162. by setting the variable 'heapstart' in cfport.c. The programmer should
  163. pick a number large enough to accommodate the environment in which development
  164. is taking place. If C++ is used, static constructors can gobble a lot of
  165. space before cfinit() is called. The command cfcreep() returns the amount
  166. of space in the safety zone. WARNING: you can't change heapstart after
  167. permanent categories have been saved in a file.
  168.  
  169. The named filesystem can hold permanent categories for multiple applications
  170. providing the applications are uniquely identified by the first argument
  171. to cfinit().
  172.  
  173. In a clean design, a programmer would save a small number of pointers (one??)
  174. to a complex memory structure which will come and go automatically as the
  175. application is run. The purpose here is to speed up the process of loading
  176. permanent objects. Some CAD programs take 30 minutes to start; with CFF
  177. startup can be reduced to seconds on similarly endianed machines.
  178.  
  179. for example:
  180.  
  181. main()
  182. {
  183. struct masterstruct *masterptr;
  184.     
  185.     cfinit("myapp", 256,"myfile.cff");  // PERMINFO is now defined
  186.     if(!cfisnew(PERMINFO))
  187.     {/* The file is not new, load the saved copy of masterptr */
  188.         cfget(PERMINFO, "masterptr", 9, &masterptr, sizeof(void *));
  189.     }
  190.     else
  191.     {/* The file is new, build the basic structures */
  192.         masterptr = mallocC(-1, sizeof(masterstruct)); // or whatever
  193.  
  194.         ...  // build memory structures based on masterptr
  195.              // and various negative categories
  196.     }
  197.  
  198.     ...  // use and modify the permanent structures
  199.          // always use negative categories
  200.  
  201.     /* Save the master pointer before exit */
  202.     cfreput(PERMINFO, "masterptr", 9, &masterptr, sizeof(void *));
  203.     cfexit();
  204. }
  205.  
  206. PREDEFINED PATHNAMES (use as the leading element of a path)
  207.  
  208.     MEMORY    the memory filesystem
  209.     EXTDMEM   the extended memory filesystem
  210.  
  211. PREDEFINED PATHNAMES or HANDLES (use as the leading element or as a handle)
  212.  
  213.     PERMFILE  the filesystem which was mentioned in cfinit()
  214.     PERMCAT   an object in PERMFILE containing the app's permanent categories
  215.     PERMINFO  an object in PERMFILE into which the user can store app info
  216.  
  217.  
  218. PREDEFINED HANDLE (use only as a handle)
  219.  
  220.     MEMTEMP    a memory object which can be used by the programmer
  221.  
  222. ALIGNMENT
  223.  
  224. The granularity of the 5.9 release is 4 bytes for malloc and 32 bytes
  225. for filesystem allocations. I am considering allowing each bitmap to 
  226. carry a different alignment, if all programmers used gcc then I could
  227. use long long arguments in the user API.
  228.  
  229. NODE SIZES
  230.  
  231. Node (bucket) sizes can range from 512 bytes to 8192 bytes. When an
  232. object is created, the default size is 2048 bytes. The programmer can
  233. modify this size by setting a flag in the mode bits for cfopen. The
  234. root directory of a filesystem is defaulted to 1024 bytes per node.
  235.  
  236.         F_FILEONLY      512 bytes
  237.         F_BIGDIR        4096 bytes
  238.         F_HUGEDIR       8192 bytes
  239.         
  240.  
  241. KEYS, ITEMS and DATA
  242.  
  243. Keys are the names of things in the filesystem. When used as part of a 
  244. path the key must contain only characters in the range 0x40 to 0x7f 
  245. (space to tilde) or it will be rejected by the name translation mechanism.
  246. In all other cases a key may contain anything. When using hashed objects
  247. the programmer should make a distinction between long and short keys.
  248. Short keys are 8 bytes or less and are stored directly in the hash buckets
  249. along with Items. Long keys are stored in a special KEYCACHE area and
  250. require the overhead of the hash bucket entry which is 20 bytes plus
  251. the overhead of the KEYCACHE which is 13 bytes + the size of the key.
  252. Note: the minimum KEYCACHE allocation is 32 bytes. When a long key is
  253. stored in a hash bucket the 8 byte key region is converted to an alternative
  254. hash value for the key, this ensures that only one key comparison
  255. is ever done. B+ tree objects store the keys and items together in the
  256. tree nodes. The programmer should ensure that at least 2 keys will fit
  257. into a B+ tree node, 1 key per node results in a B tree.
  258.  
  259. The key comparison routine can be set for each object with the command
  260. cfkeycmp(handle, funcaddr);
  261.  
  262. Items are the basic insertable/retrievable elements in a node. They are
  263. 64 bits in size with the high 4 bits reserved for tags. B+ trees can support
  264. untagged items if created with F_UNTAGGED set.
  265.  
  266. The programmer will find that 64 bit items are a bit of a pain, especially
  267. if his compiler does not support the long long type. They are worth the
  268. extra effort, believe me.
  269.  
  270. When the system stores a tagged item it checks the high 4 bits, if they
  271. are non-zero it assumes that a tag is already present, otherwise the
  272. item is tagged as a STO_VALUE. Be SURE that your program generated items
  273. have the high 4 bits set to zero.
  274.  
  275. Due to the tagged nature of most items, the system can automatically allocate
  276. and deallocate storage if the item happens to describe a chunk of data.
  277. Currently the maximum size of a single contiguous chunk is 16 Megabytes -1.
  278. This can change if I implement adjustable alignment per bitmap.
  279. See the file cff.h for tag values.
  280.  
  281. The item comparison routine can be set for each object with the command
  282. cfitemcmp(handle, funcaddr);
  283.  
  284. A copy of the default keycmp and itemcmp functions are located in the
  285. module cfport.c so that the programmer can see what needs to be done for
  286. alternative functions.
  287.  
  288.  
  289. HASHED vs SORTED
  290.  
  291. The default method for an object is hashed. The root directory of a
  292. filesystem is forced to be hashed even if created as F_SORTED. Thus
  293. a SORTED object cannot become a filesystem with the cfcopy command.
  294. I may change this but it complicates opening a filesystem.
  295.  
  296. SORTED pros
  297. 1. Sequential access of a sorted object produces sorted output.
  298. 2. Sorted objects can support untagged items, no subobjects are allowed.
  299. 3. Normal mode duplicate entries have the overhead of only one key per node.
  300. 4. An unlimited number of normal mode duplicate entries is supported.
  301. 5. There is no in-core index for the nodes. This could be important for
  302.    an object with 100 million items.
  303. 6. Inserts and deletes to sorted objects do not invalidate the mark.
  304.  
  305. SORTED cons
  306. 1. Access and update of sorted objects is MUCH slower than hashed.
  307. 2. Key length is limited by the node size.
  308.  
  309. HASHED pros
  310. 1. Hashed objects are fast to update and access, and VERY fast with short keys.
  311. 2. Key length is unlimited (16 Megabytes).
  312. 3. Hashed objects can be created with PREALLOCATED entries and data. This
  313.    produces complete locality of reference and great speed when creating
  314.    a database.
  315.  
  316. HASHED cons
  317. 1. The in-core index for each object takes up space (4 bytes per bucket).
  318.    This is a consideration when the object contains a lot of items. The
  319.    maximum bucket of 8192 bytes contains 406 items.
  320. 2. Normal mode duplicate entries is limited to 406 dups.
  321. 3. Under pathological conditions the hashed object may fill up, i.e. a
  322.    bucket may contain a mix of keys which cannot be split.
  323. 4. Sequential access to a hashed object produces unsorted output.
  324.  
  325.  
  326.  
  327. DUPLICATE ENTRIES
  328.  
  329. Keys with duplicate entries are supported in two ways: the normal
  330. `dupnum' way and the `dupname' way. Dupnames are 48 bit unique names + a 12 bit
  331. unique id. Each object can support and control 4093 dupname sets.
  332. Dupnames can be used as keys or items. Normal dups must be accessed by
  333. a key-item combination or sequentially; the items for each normal 
  334. dup should be different.
  335. DO NOT MIX NORMAL AND DUPNAME DUPLICATES.
  336.  
  337.  
  338. OBJECTS AS FILES
  339.  
  340. Any object is a file, just read and write to it. If you read
  341. before writing, read will return ERROR. When an object is closed
  342. space allocated to the file property is truncated to within 128 bytes
  343. of the filesize, filesize is limited to 2G bytes.
  344.  
  345.  
  346. OBJECTS AS STACKS
  347.  
  348. Any object is a stack, just push and pop items or data. Stacks retain
  349. their data when an object is closed and/or copied, stack depth is unlimited.
  350.  
  351. OBJECTS AS DIRECTORIES
  352.  
  353. Any object is a directory, just create a subobject (subdirectory) with
  354. the cfopen or cfsubopen commands. The directory property can be accessed
  355. with cfopendir, cfreaddir, cfrewinddir, cftelldir, cfseekdir and cfclosedir.
  356.  
  357.  
  358. OBJECTS AS DICTIONARIES
  359.  
  360. Any object is an dictionary, just insert, find and delete keyed items.
  361. To find out what is in an object, issue the command cfprintentries(something).
  362.  
  363. OBJECTS AS REPOSITORIES
  364.  
  365. Any object is a repository, just put and get keyed data chunks 
  366. (max 16Meg per chunk, min 32 bytes per chunk).
  367.  
  368.  
  369. INTERNAL BUFFERING
  370.  
  371. The 5.9 version supports 512 buffer headers and unlimited data
  372. buffering. The cfinit command includes an argument for the number of 1K blocks
  373. of data buffering allowed. cfinit("app",700,NULL) designates that 700K of 
  374. memory be allocated to buffering.
  375.  
  376. Data chunks can be accessed directly in the buffer region with the command
  377. cflocalize(). The localizer will allow most of the defined
  378. data region to be allocated to a single localization request, excess
  379. buffers are flushed. The size of the data region may be increased/decreased
  380. dynamically with the cfmodbufs() command.
  381.  
  382. This localizer does not localize blocks; it localizes chunks which may
  383. be large or small. Most of the time the localizer is working with nodes
  384. and keys so the memory reqirements are not large internally. The file
  385. property is read/written in 8K chunks. If the user creates a huge chunk
  386. then it is up to the user to deal with it.
  387.  
  388. Huge data chunks can be accessed with the command cfopen_chunk() or cfopen()
  389. followed by reads and writes to the returned handle.
  390.  
  391.  
  392. LAZY WRITING
  393.  
  394. The writethrough properties of an object can be set with the commands
  395. cfsetlazy(handle) and cfsetverylazy(handle). The command cfclrlazy(handle)
  396. causes the object and all underlying buffers, including the OS, to be flushed.
  397. The default writethrough property of an object causes it to be up to date
  398. at the user API level. By this I mean that the CFF buffers are written to
  399. the OS buffers. In order to ensure that the OS buffers are flushed, the
  400. programmer should issue cfflush(handle) and cfsync() commands when appropriate.
  401.  
  402.  
  403. BITMAPS
  404.  
  405. The term 'bitmaps' is misleading. CFF uses extent maps which are 512 bytes
  406. in size and contain 49 sorted entries per map. Each bitmap set has an
  407. in-core sorted index. The root directory of each filesystem has a bitmap
  408. set by default. Individual objects can be created with a bitmap which
  409. will control space allocation for the object and it's subobjects. If an
  410. object has a bitmap it can be deleted very quickly, the system merely returns
  411. all the space defined by the maps to the parent maps. Without a bitmap the
  412. deletion of a complex object can take a while. Nevertheless, DO NOT USE
  413. BITMAPS unless you know what you are doing. This is because they lead to
  414. fragmentation in any environment that involves active insertions and deletions.
  415. Preferably you would pre-allocate all the anticipated space to the bitmap
  416. when you create the object, but this usually means that you allocate a lot
  417. more than is really needed. To find out more about bitmaps, issue the command
  418. cfprintbitmaps(something). Hashed objects which have preallocated data and
  419. entries do not return space to the controlling bitmaps when something
  420. is deleted, this is good. To shrink a sparsely populated preallocated hashed 
  421. object, copy it.
  422.  
  423. CFF maintains two caches for each set of bitmaps, the KEYCACHE is used
  424. for storage of hashed keys and tends to segregate long keys from the data,
  425. this is good; the CACHE is used to dispense space for data, and nodes.
  426. Bitmaps are stored in the space that they map; often as the first 512
  427. bytes.
  428.  
  429.  
  430. GARBAGE COLLECTION
  431.  
  432. The system actively returns space to the underlying bitmaps and
  433. also coalesces the bitmaps in a timely manner. The system currently does not
  434. compress an object or filesystem in place, i.e. rearrange the placement
  435. of things so that the end of a bitmap contains a nice chunk of space that
  436. can be returned to it's parent. cfcopy() is the rich man's substitute.
  437.  
  438.  
  439. ERROR REPORTING
  440.  
  441. Version 5.9 has very uninformative error reporting.
  442.  
  443.  
  444. ACCESS CONTROL and SECURITY
  445.  
  446. Version 5.9 has no access control or security.
  447.  
  448.  
  449. FILE AND RECORD LOCKING
  450.  
  451. Version 5.9 has no locks.
  452.  
  453.  
  454. DATA COMPRESSION
  455.  
  456. An adaptation of lz77 is used to achieve automatic data compression of
  457. permanent categories. Two calls, cfzip() and cfunzip() are provided
  458. for the programmer.
  459.  
  460.  
  461. STDIO STYLE I/O
  462.  
  463. A set of 'stream' calls is included. These calls work with objects, data 
  464. chunks, values, external files and raw devices. There are several additional
  465. opening modes: unique,temp,string,stat,text,binary.
  466.  
  467.  
  468. INFORMATIONAL PRINTING
  469.  
  470. The programmer can set the system print function with the command
  471. cfsetprintfunc(int (*funcptr)(int));
  472.  
  473. The print function prints one character at a time and returns 1 if OK
  474. and -1 if a device error.
  475.  
  476. The default print function calls PORTPRINT in cfport.c which writes
  477. one character to file descriptor 1. Unbuffered printing gets you all
  478. there is to see even when the system aborts.
  479.  
  480. CFF contains a built in printf 'cfeprintf' which is reentrant and
  481. prints one character at a time.
  482.  
  483.  
  484. cfprintbitmaps(void *something);
  485. Prints the bitmaps of something (a path or handle) and it's parents.
  486.  
  487.  
  488. cfprintentries(void *something);
  489. Prints the contents of the storage maps of something (a path or handle).
  490.  
  491.  
  492. cfpflags(char *label, void *handle)
  493. Prints the flags for an open object and its parents, 
  494. adds a programmer supplied label string.
  495.  
  496.  
  497.  
  498. THE COMMAND SET
  499.  
  500. NOTATION:
  501. void *something     Denotes a path or handle (use either one). 
  502.                     If a path, the object need not be open.
  503. void *handle        Denotes a handle for an open object or data chunk.
  504.  
  505.  
  506.  
  507. INITIALIZATION AND EXIT
  508.  
  509. void cfinit(
  510.               char *appname,    // the name of the application
  511.               int bufferspace,  // size of buffer area in KB
  512.               char *permfile    // path of file containing permanent objs
  513.            )
  514. Initialize, load permanent malloc categories from permfile,
  515. load application and system string definitions from permfile,
  516. define PERMFILE, PERMCAT and PERMINFO to refer to the appropriate
  517. objects in permfile, add 'cfexit()' to the atexit list.
  518.  
  519.  
  520. void cfexit(
  521.             void
  522.            )
  523. Save permanent malloc categories, save current application and system string
  524. definitions, close all open objects.
  525.  
  526.  
  527. OPEN CLOSE READ WRITE etc.
  528.  
  529. typedef struct opninfo {
  530.     long initial_entries;  // if hashed object, preallocates buckets
  531.     unsigned long bitmap_prealloc;  // if object has bitmap, initial space
  532.     long data_prealloc;    // if hashed object, data space per initial entry
  533. } OPNINFO;
  534.  
  535. /* OPEN MODE BITS */
  536.  
  537. #define F_RDONLY    0x0001     // The object is readonly, the parents are rdwr
  538. #define F_WRONLY    0x0002     // I don't think this works
  539. #define F_RDWR      0x0003
  540. #define F_CREAT     0x0004     // create if non-existant
  541. #define F_TEMP      0x0008     // delete on close
  542. #define F_UNIQ      0x0010     // create a unique name and append to path
  543. #define F_EXCL      0x0020     // non shared open
  544. #define F_BITMAP    0x0040     // attach a bitmap
  545. #define F_TRUNC     0x0080     // truncate on open
  546. #define F_APPEND    0x0100     // only append when writing to file
  547. #define F_FILEONLY  0x0400     // 512 byte nodes
  548. #define F_BIGDIR    0x0800     // 4096 byte nodes
  549. #define F_HUGEDIR   0x1000     // 8192 byte nodes
  550. #define F_SORTED    0x8000     // B+ tree
  551. #define F_UNTAGGED  0x10000    // items are untagged if B+ tree
  552. #define F_STAT      0x20000    // The object and parents are readonly
  553.  
  554. void *cfopen(
  555.                 char *path,        // pathname of object
  556.                 long mode,        // open mode bits
  557.                 void *info        // pointer to OPNINFO struct or NULL
  558.             )
  559. Returns an opaque handle or NULL, check errno.
  560. Will also open a chunk or value for read/write
  561. (the path must contain only legal chars).
  562.  
  563.  
  564. void *cfsubopen(
  565.                 void *handle,    // handle of open object
  566.                 void *name,        // name of subobject
  567.                 long mode,        // open mode bits
  568.                 void *info        // pointer to OPNINFO struct or NULL
  569.                )                
  570. Pastes the path, this is a convenience for the programmer.
  571. If name is NULL or name[0] == 0, then reopens handle.
  572. Returns an opaque handle or NULL, check errno.
  573. Will also open a chunk or value for read/write
  574. (the name must contain only legal chars).
  575.  
  576.  
  577. void *cfopen_chunk(
  578.                    void *handle,    // handle of open object
  579.                    void *item        // pointer to an Item describing a chunk
  580.                   )
  581. Permits read/write access to a fixed length chunk of data.  
  582. Use cfclose() when finished.
  583. Returns an opaque handle or NULL, check errno.
  584.  
  585.  
  586. void *cfmake_chunk(
  587.                     void *handle,    // handle of open object
  588.                     void *key,        // pointer to key
  589.                     int keylen,        // length of key
  590.                     int chunksize    // size of chunk, 16Meg max
  591.                     )
  592.  
  593. Creates a chunk in the open object, providing that the open object
  594. is not a chunk and is not an external file. Chunks are fixed length
  595. and can be read/written but not extended.
  596. Returns an opaque handle which can be used with cfread, cfwrite, cfclose,
  597. cfdup, cfreopen, cfdopen etc.
  598.  
  599.  
  600. void* cfdup(
  601.             void *handle    // handle of open object.
  602.             )
  603.  
  604. Same as dup() in unix, shared filepointer.
  605. Use cfclose() when finished.
  606. Returns an opaque handle or NULL, check errno.
  607.  
  608.  
  609. void* cfreopen(
  610.             void *handle    // handle of open object.
  611.             )
  612.  
  613. The reopened handle has an independant filepointer which is set to the
  614. position of the original, NOTE this reopen is UNCONDITIONAL, unlike cfsubopen()
  615. with a NULL name.
  616. Use cfclose() when finished.
  617. Returns an opaque handle or NULL, check errno.
  618.  
  619.  
  620. void cfclose(
  621.              void *handle
  622.              )
  623. Closes and flushes whatever is referenced by the handle.
  624. If an object or file has been created with F_TEMP, it is deleted on close.
  625.  
  626.  
  627. void cfflush(
  628.              void *handle
  629.              )
  630. Ensures that all information pertaining
  631. to the object or external file is written out.
  632.  
  633. void cfsync()
  634. Ensures that all information pertaining
  635. to all open objects and external files is written out.
  636. NOTE -- this may not work, depends upon the supporting OS.
  637.  
  638.  
  639. long cfread(
  640.             void *handle,
  641.             void *userbuffer,
  642.             long amount
  643.             )
  644. Reads from a file or a chunk.
  645. Returns amount read or ERROR, check errno.
  646.  
  647. long cfwrite(
  648.              void *handle,
  649.              void *userbuffer,
  650.              long amount
  651.             )
  652. Writes to a file or a chunk.
  653. Returns amount written or ERROR, check errno.
  654.  
  655. long cfseek(
  656.             void *handle,
  657.             unsigned long amount,
  658.             int mode
  659.            )
  660. Seeks within a file or a chunk.
  661. It is legal to seek past the end of a file.
  662. CFF Version 5.9 files do not have holes.
  663. Returns position or ERROR
  664.  
  665. /* Seek modes */
  666. #define S_SET 0
  667. #define S_CUR 1
  668. #define S_END 2
  669.  
  670. int cftruncate(
  671.                void *something,
  672.                unsigned long size
  673.               )
  674. Truncates the file property to 'size', returns OK or ERROR
  675.  
  676.  
  677.  
  678. SEQUENTIAL DIRECTORY ACCESS -- JUST LIKE POSIX almost
  679.  
  680. typedef struct cfdirent {
  681.     int d_namlen;
  682.     char *d_name;
  683.     unsigned long d_bytesalloc;
  684.     unsigned long d_bytesused;
  685.     unsigned long d_mode;
  686.     unsigned long d_entrycnt;
  687.     void *d_fpt;
  688. } CFDIRENT;
  689.  
  690. void *cfopendir(
  691.                 void *something,   // path or handle
  692.                )
  693. Opens the directory and dictionary aspects of a path or handle.
  694. Works for external files.
  695. Returns opaque handle, or NULL, check errno.
  696.  
  697.  
  698. void cfclosedir(
  699.                 void *openhandle
  700.                )
  701. Close using the handle produced by cfopendir.
  702.  
  703.  
  704. CFDIRENT *cfreaddir(
  705.                     void *openhandle
  706.                    )
  707. Returns a pointer to a CFDIRENT struct, or NULL if EOD.
  708. The nodes (sub-directories) are returned.
  709.  
  710. CFDIRENT *cfreadfulldir(
  711.                     void *openhandle
  712.                    )
  713. Returns a pointer to a CFDIRENT struct, or NULL if EOD.
  714. Nodes, values and chunks are returned.
  715.  
  716. void cfrewinddir(
  717.                  void *openhandle
  718.                 )
  719. Reset to beginning of directory.
  720.  
  721.  
  722. void cftelldir(
  723.                void *openhandle,
  724.                STOR *curentry
  725.               )
  726. Returns a pointer to the current directory entry.
  727.  
  728.  
  729. void cfseekdir(
  730.                void *openhandle,
  731.                STOR *curentry
  732.               )
  733. Sets the directory search to the spot returned by cftelldir.
  734.  
  735.  
  736. SEQUENTIAL INDEX ACCESS
  737.  
  738. long cfhead(
  739.             void *handle,
  740.             Item *itemptr
  741.            )
  742. Goto beginning of entries, get current item.
  743. Returns OK or ERROR, 
  744.  
  745. long cfhead_dupnum(
  746.                    void *handle
  747.                    void *keyptr,
  748.                    int   keylen,
  749.                    void *itemptr
  750.                   )
  751. Goto beginning of normal duplicate entries for the key, get current item.
  752. Returns OK or ERROR
  753.  
  754. long cfhead_dupname(
  755.                    void *handle
  756.                    void *keyptr,
  757.                    int   keylen,
  758.                    void *itemptr
  759.                   )
  760. Goto beginning of DupName duplicate entries for the key, get current item.
  761. Returns OK or ERROR
  762.  
  763. long cftail(
  764.             void *handle,
  765.             Item *itemptr
  766.            )
  767. Goto end of entries, get current item.
  768. Returns OK or ERROR, 
  769.  
  770. long cftail_dupnum(
  771.                    void *handle
  772.                    void *keyptr,
  773.                    int   keylen,
  774.                    void *itemptr
  775.                   )
  776. Goto end of normal duplicate entries for the key, get current item.
  777. Returns OK or ERROR
  778.  
  779. long cftail_dupname(
  780.                    void *handle
  781.                    void *keyptr,
  782.                    int   keylen,
  783.                    void *itemptr
  784.                   )
  785. Goto end of DupName duplicate entries for the key, get current item.
  786. Returns OK or ERROR
  787.  
  788. long cfnext(
  789.             void *handle,
  790.             Item *itemptr
  791.            )
  792. Goto next sequential entry, get current item.
  793. Returns OK, EOI or ERROR, 
  794.  
  795. long cfnext_dupnum(
  796.                    void *handle
  797.                    void *keyptr,
  798.                    int   keylen,
  799.                    void *itemptr
  800.                   )
  801. Goto next normal duplicate entry for the key, get current item.
  802. Returns OK, EOI or ERROR
  803.  
  804. long cfnext_dupname(
  805.                    void *handle
  806.                    void *keyptr,
  807.                    int   keylen,
  808.                    void *itemptr
  809.                   )
  810. Goto next DupName duplicate entry for the key, get current item.
  811. Returns OK, EOI or ERROR
  812.  
  813. long cfprev(
  814.             void *handle,
  815.             Item *itemptr
  816.            )
  817. Goto previous sequential entry, get current item.
  818. Returns OK, BOI or ERROR, 
  819.  
  820. long cfprev_dupnum(
  821.                    void *handle
  822.                    void *keyptr,
  823.                    int   keylen,
  824.                    void *itemptr
  825.                   )
  826. Goto previous normal duplicate entry for the key, get current item.
  827. Returns OK, BOI or ERROR
  828.  
  829. long cfprev_dupname(
  830.                    void *handle
  831.                    void *keyptr,
  832.                    int   keylen,
  833.                    void *itemptr
  834.                   )
  835. Goto previous DupName duplicate entry for the key, get current item.
  836. Returns OK, BOI or ERROR
  837.  
  838. long cfkey(
  839.            void *handle,
  840.            void *keybufptr,
  841.            int keybuflen
  842.           )
  843. Returns OK, BOI, EOI or ERROR.
  844. If OK, fills the buffer denoted by 'keybufptr' with no more than
  845. 'keybuflen' bytes of the current key.
  846.  
  847. long cfitem(
  848.             void *handle,
  849.             Item *itemptr
  850.            )
  851. Get item from current position.
  852. Returns OK, BOI, EOI or ERROR.
  853.  
  854. long cfdata(
  855.            void *handle,
  856.            void *databufptr,
  857.            int databuflen
  858.           )
  859. Returns OK, BOI, EOI or ERROR if invalid handle or no data available.
  860. If OK, fills the buffer denoted by 'databufptr' with no more than
  861. 'databuflen' bytes of the current key's data area, if it exists.
  862.  
  863.  
  864. long cfkeylen(
  865.               void *handle,
  866.               int *len
  867.              )
  868. returns OK if a current key exists, len is set to the length of the key
  869. NOTE: Short hashed keys always return a length of 8, even if they
  870. were originally shorter.
  871.  
  872.  
  873. long cfdatalen(
  874.                void *handle,
  875.                int *len
  876.               )
  877. returns OK if a current key exists, len is set to data size or 0 if no data
  878.  
  879.  
  880. long cfmark(
  881.             void *handle
  882.            )
  883. Saves the current position. (see cffind_mark()).
  884. Returns OK or ERROR.
  885.  
  886.  
  887. INSERT ITEMS
  888.  
  889. int cfinsert(
  890.               void *handle,
  891.               void *keyptr,
  892.               int   keylen,
  893.               void *itemptr
  894.              )
  895. Returns OK or ERROR, duplicate entries are not allowed
  896.  
  897. int cfreinsert(
  898.               void *handle,
  899.               void *keyptr,
  900.               int   keylen,
  901.               void *itemptr
  902.              )
  903. Returns OK or ERROR, the key must exist, duplicate entries are not allowed.
  904. If the existing item references data, the data space is deleted.
  905.  
  906. int cfinsert_dupnum(
  907.                      void *handle,
  908.                      void *keyptr,
  909.                      int   keylen,
  910.                      void *itemptr,
  911.                      long *dupcnt    // returns the current dupcnt, 1 based
  912.                     )
  913. Returns OK or ERROR, 'normal' duplicates are allowed.
  914.  
  915. int cfreinsert_dupnum(
  916.                      void *handle,
  917.                      void *keyptr,
  918.                      int   keylen,
  919.                      void *itemptr,
  920.                      long *dupnum    // points to the desired dupnum, 0 based
  921.                     )
  922. Returns OK or ERROR, the key and dupnumn'th duplicate must exist.
  923. If the existing item references data, the data space is deleted.
  924.  
  925. NOTE: Items entered as normal duplicates do not remain in the order
  926.       in which they are entered, B+ trees sort the keys and items,
  927.       hashed directories get rearranged when split. Therefore, reinserting
  928.       to a specific dupnum is a chancy business and should be done only
  929.       when the programmer is certain of the algorithm.
  930.  
  931.  
  932. int cfinsert_dupname(
  933.                      void *handle,
  934.                      void *keyptr,
  935.                      int   keylen,
  936.                      void *itemptr,
  937.                      DupName *dupname  // returns current dupname
  938.                      )
  939. Returns OK or ERROR, the value referenced by 'dupname' is filled with the
  940. current DupName.
  941.  
  942. NOTE: DupNames are constantly incremented and provide a completely unique
  943. way to identify a key-item pair. Each DupName contains a 48 bit counter
  944. that is decremented only under special circumstances (see cfdelete_lastdupname).
  945. If a program inserted 1000 dupnames per second, it would take more than 8000 
  946. years to overflow the counter.
  947.  
  948.  
  949.  
  950.  
  951.  
  952. int cfreinsert_dupname(
  953.                      void *handle,
  954.                      void *keyptr,
  955.                      int   keylen,
  956.                      void *itemptr,
  957.                      DupName *dupname    // points to the desired DupName
  958.                      )
  959. If the existing item references data, the data space is deleted.
  960. Returns OK or ERROR, the key and dupname'th duplicate must exist.
  961.  
  962.  
  963. INSERT DATA
  964.  
  965. NOTE: 1. Data may not be inserted in objects with untagged items.
  966.       2. reput acts like realloc, if the entry doesn't exist it is created.
  967.          If dupnums or DupNames are used with reput, then the desired entry
  968.          must exist or the operation fails.
  969.  
  970. void *cfput(
  971.             void *handle,
  972.             void *keyptr,
  973.             int   keylen,
  974.             void *databuffer,
  975.             long  databuflen,
  976.             void *itemptr    // if non NULL then the Item is filled in
  977.            )
  978. Returns 'itemptr' if successful, NULL if not.
  979. The Item referenced by 'itemptr' describes a data chunk.
  980. If itemptr is NULL, then the non-NULL value returned on success is not
  981. a valid itemptr in its own right.
  982.  
  983.  
  984. void *cfreput(
  985.             void *handle,
  986.             void *keyptr,
  987.             int   keylen,
  988.             void *databuffer,
  989.             long  databuflen,
  990.             void *itemptr     // if non NULL then the Item is filled in
  991.            )
  992. Overwrites old data, if no old data, a new entry is created.
  993. Returns 'itemptr' if successful, NULL if not.
  994. The Item referenced by 'itemptr' describes a data chunk.
  995. If itemptr is NULL, then the non-NULL value returned on success is not
  996. a valid itemptr in its own right.
  997.  
  998.  
  999. void *cfput_dupnum(
  1000.                    void *handle,
  1001.                    void *keyptr,
  1002.                    int   keylen,
  1003.                    void *databuffer,
  1004.                    long  databuflen,
  1005.                    void *itemptr,
  1006.                    long *dupcnt      // returns the current dupcnt, 1 based
  1007.                   )
  1008. Returns 'itemptr' if successful, NULL if not.
  1009. The Item referenced by 'itemptr' describes a data chunk.
  1010. If itemptr is NULL, then the non-NULL value returned on success is not
  1011. a valid itemptr in its own right.
  1012.  
  1013.  
  1014. void *cfreput_dupnum(
  1015.                    void *handle,
  1016.                    void *keyptr,
  1017.                    int   keylen,
  1018.                    void *databuffer,
  1019.                    long  databuflen,
  1020.                    void *itemptr,    // if non NULL then the Item is filled in
  1021.                    long *dupnum      // references the desired dupnum, 0 based
  1022.                   )
  1023. Overwrites old data, if no old data, the operation fails.
  1024. Returns 'itemptr' if successful, NULL if not.
  1025. The Item referenced by 'itemptr' describes a data chunk.
  1026. If itemptr is NULL, then the non-NULL value returned on success is not
  1027. a valid itemptr in its own right.
  1028.  
  1029.  
  1030. void *cfput_dupname(
  1031.                    void *handle,
  1032.                    void *keyptr,
  1033.                    int   keylen,
  1034.                    void *databuffer,
  1035.                    long  databuflen,
  1036.                    void *itemptr,    // if non NULL then the Item is filled in
  1037.                    DupName *dupname  // returns the current DupName
  1038.                   )
  1039. Returns 'itemptr' if successful, NULL if not.
  1040. The Item referenced by 'itemptr' describes a data chunk.
  1041. If itemptr is NULL, then the non-NULL value returned on success is not
  1042. a valid itemptr in its own right.
  1043.  
  1044.  
  1045. void *cfreput_dupname(
  1046.                    void *handle,
  1047.                    void *keyptr,
  1048.                    int   keylen,
  1049.                    void *databuffer,
  1050.                    long  databuflen,
  1051.                    void *itemptr,      // if non NULL the Item is filled in
  1052.                    DupName *dupname    // references the desired DupName
  1053.                   )
  1054. Overwrites old data, if no old data, the operation fails.
  1055. Returns 'itemptr' if successful, NULL if not.
  1056. The Item referenced by 'itemptr' describes a data chunk.
  1057. If itemptr is NULL, then the non-NULL value returned on success is not
  1058. a valid itemptr in its own right.
  1059.  
  1060.  
  1061. RETRIEVE DATA
  1062.  
  1063. long cfget(
  1064.            void *handle,
  1065.            void *keyptr,
  1066.            void  keylen,
  1067.            void *databufptr,
  1068.            long  databuflen
  1069.           )
  1070. Read the data for the first item of the key into the buffer for no 
  1071. more than 'databuflen' bytes;
  1072. Returns FOUND, FOUND+1 if dups present, NOTFOUND, or ERROR
  1073. if >= FOUND sets up for sequential access.
  1074.  
  1075. int cfqget(
  1076.            void *handle,
  1077.            void *keyptr,
  1078.            int   keylen,
  1079.            void *databufptr,
  1080.            int    databuflen
  1081.           )
  1082. Read the data or item value of the key. If item value, buflen == 8.
  1083. i.e. if data is stored you get it; if the data is really a value you get
  1084. the 60 bit value + 4 bits of tag in the high 4 bits.
  1085. OPTIMIZED FOR SPEED, only works for memory based hash dictionaries.
  1086. Returns FOUND, NOTFOUND, or ERROR
  1087.  
  1088.  
  1089. long cfget_dupnum(
  1090.                   void *handle,
  1091.                   void *keyptr,
  1092.                   int   keylen,
  1093.                   void *databufptr,
  1094.                   long  databuflen,
  1095.                   long *dupnum      // references the desired dupnum, 0 based
  1096.                  )
  1097. Read the data for the dupnum'th item of the key into the buffer for no 
  1098. more than 'databuflen' bytes;
  1099. Returns FOUND, FOUND+1, NOTFOUND or ERROR. 
  1100. If >= FOUND, sets up for sequential access.
  1101.  
  1102.  
  1103. long cfget_dupname(
  1104.                   void *handle,
  1105.                   DupName *dupname,  // points to the desired DupName
  1106.                   void *databufptr,
  1107.                   long  databuflen
  1108.                  )
  1109. Read the data for the dupname into the buffer for no 
  1110. more than 'databuflen' bytes;
  1111. Returns FOUND, NOTFOUND or ERROR.
  1112. If FOUND, sets up for sequential access.
  1113.  
  1114.  
  1115. FIND ITEMS
  1116.  
  1117. int cffind(
  1118.            void *handle,
  1119.            void *keyptr,
  1120.            int   keylen,
  1121.            void *itemptr   // if FOUND the item is returned
  1122.           )
  1123. Locates the first item of a key, and sets up for sequential access.
  1124. Returns FOUND, FOUND+1 if dups present, NOTFOUND, or ERROR
  1125.  
  1126. int cfqfind(
  1127.            void *handle,
  1128.            void *keyptr,
  1129.            int   keylen,
  1130.            Item *keyi;    // or NULL
  1131.            Item *dati;    // or NULL
  1132.           )
  1133. Returns pointers to the key and data, and FOUND, NOTFOUND or ERROR;
  1134. OPTIMIZED FOR SPEED, only works for memory based hash dictionaries.
  1135.  
  1136. int cfqfinddat(
  1137.            void *handle,
  1138.            void *keyptr,
  1139.            int   keylen,
  1140.            Item *dati;
  1141.           )
  1142. Returns pointer to the data, and FOUND, NOTFOUND or ERROR;
  1143. dati.a1 points to data
  1144. data.a2.size is data size;
  1145. OPTIMIZED FOR SPEED, only works for memory based hash dictionaries.
  1146.  
  1147. int cfqfindkey(
  1148.            void *handle,
  1149.            void *keyptr,
  1150.            int   keylen,
  1151.            Item *keyi;
  1152.           )
  1153. Returns pointer to the key, and FOUND, NOTFOUND or ERROR;
  1154. keyi.a1 points to the key;
  1155. OPTIMIZED FOR SPEED, only works for memory based hash dictionaries.
  1156.  
  1157. int cffind_dupnum(
  1158.                   void *handle,
  1159.                   void *keyptr,
  1160.                   int   keylen,
  1161.                   void *itemptr,    // if FOUND the item is returned
  1162.                   long *dupnum      // points to the desired dupnum, 0 based
  1163.                  )
  1164. Returns FOUND, NOTFOUND or ERROR. 
  1165. If ==  FOUND, sets up for sequential access.
  1166.  
  1167.  
  1168. int cffind_dupname(
  1169.                   void *handle,
  1170.                   DupName *dupname  // points to the desired dupname
  1171.                   void *itemptr,    // if FOUND the item is returned
  1172.                  )
  1173. Returns FOUND, NOTFOUND or ERROR. If FOUND, sets up for sequential access.
  1174.  
  1175.  
  1176. int cffind_item(
  1177.                 void *handle,
  1178.                 void *keyptr,
  1179.                 int   keylen,
  1180.                 void *itemptr
  1181.                )
  1182. Locates a key-item pair.
  1183. Returns FOUND, NOTFOUND or ERROR. If FOUND, sets up for sequential access.
  1184.  
  1185.  
  1186. int cffind_mark(
  1187.                 void *handle,
  1188.                 void *itemptr
  1189.                )
  1190. Returns the item for the current mark if the mark is valid (see cfmark()).
  1191. The mark can be invalidated if items are inserted or deleted after the
  1192. mark is set. This phenomenon happens more often with hashed directories
  1193. than with B+ trees.
  1194.  
  1195. Returns FOUND, NOTFOUND or ERROR. If FOUND, sets up for sequential access.
  1196.  
  1197.  
  1198.  
  1199. DELETE ITEMS
  1200.  
  1201. int cfdelete(
  1202.               void *handle,
  1203.               void *keyptr,
  1204.               int   keylen
  1205.              )
  1206. The first item of the key is deleted along with any data.
  1207. Returns OK or ERRORNUM a negative number.
  1208.  
  1209.  
  1210. int cfdelete_item(
  1211.                   void *handle,
  1212.                   void *keyptr,
  1213.                   int   keylen,
  1214.                   void *itemptr
  1215.                  )
  1216. If the key-item pair exists it is deleted along with any data.
  1217. Returns OK or ERRORNUM a negative number.
  1218.  
  1219.  
  1220. int cfdelete_dupnum(
  1221.                     void *handle,
  1222.                     void *keyptr,
  1223.                     int   keylen,
  1224.                     long  dupnum      // 0 based
  1225.                    )
  1226. If the dupnum'th item for the key exists it is deleted along with any data.
  1227. Returns OK or ERRORNUM a negative number
  1228.  
  1229.  
  1230. int cfdelete_dupname(
  1231.                      void *handle,
  1232.                      void *keyptr,
  1233.                      int   keylen,
  1234.                      DupName *dupname
  1235.                     )
  1236. If the dupname exists, it is deleted along with any data.
  1237. If the dupname is deleted, the 'holes' counter is incremented by one.
  1238. Each DupName set contains a 48 bit holes counter. (see cfcountdups()).
  1239. returns OK or ERRORNUM a negative number.
  1240.  
  1241.  
  1242. int cfdelete_lastdupname(
  1243.                          void *handle,
  1244.                          void *keyptr,
  1245.                          int   keylen
  1246.                         )
  1247. If the last DupName for the key exists, it is deleted along with any data.
  1248. The DupName counter is decremented by one.
  1249. Returns OK or ERRORNUM a negative number.
  1250.  
  1251.  
  1252. int cfdelete_lastdupnum(
  1253.                          void *handle,
  1254.                          void *keyptr,
  1255.                          int   keylen
  1256.                         )
  1257. If the last dupnum for the key exists, it is deleted along with any data.
  1258. WARNING: The last dupnum is probably not the last dup entered. B+ trees
  1259. sort all input and hashed directories are reorganized when split/coalesced.
  1260. Returns OK or ERRORNUM a negative number.
  1261.  
  1262.  
  1263. int cfdelete_alldupnames(
  1264.                          void *handle,
  1265.                          void *keyptr,
  1266.                          int   keylen
  1267.                         )
  1268. All 'DupName' entries for the key are deleted along with any data.
  1269. Returns OK or ERROR
  1270.  
  1271.  
  1272. int cfdelete_alldupnums(
  1273.                          void *handle,
  1274.                          void *keyptr,
  1275.                          int   keylen
  1276.                         )
  1277. All 'dupnum' entries for the key are deleted along with any data.
  1278. Returns OK or ERROR
  1279.  
  1280. DELETE OBJECTS 
  1281.  
  1282. int cfunlink(
  1283.               void *something, // path or object handle
  1284.               ...              // optional 2'nd arg if arg 1 is a handle
  1285.             )
  1286.  
  1287. Deletes the object denoted by 'something' and an optional second argument.
  1288. If 'something' is a path, then the target of the path is deleted.
  1289. if 'something' is a handle, then if the second argument is NULL
  1290. the object denoted by the handle is deleted. A non-NULL second argument
  1291. must be a character string which names an entry in the object's index.
  1292. The second argument must not refer to a sub_object.
  1293.  
  1294. Returns OK or ERROR if multiply opened or sub_objects open or not found.
  1295.  
  1296. NOTE: When an object is unlinked all of it's sub-objects are unlinked
  1297. and all data is returned to parent bitmaps. External files can be unlinked.
  1298.  
  1299.  
  1300. STACK OPERATIONS
  1301.  
  1302. long cfpush_value(
  1303.                  void *handle,    // an open object
  1304.                  unsigned long *valptr
  1305.                 )
  1306. Push an unsigned long integer on the objects stack.
  1307. Returns current stack depth or ERROR.
  1308.  
  1309. long cfpush_item(
  1310.                  void *handle,    // an open object
  1311.                  void *itemptr
  1312.                 )
  1313. Push the item on the objects stack.
  1314. Returns current stack depth or ERROR.
  1315.  
  1316. long cfpush_data(
  1317.                  void *handle,  // an open object
  1318.                  void *datbufptr,
  1319.                  int   datbuflen
  1320.                 )
  1321. Pushes data onto the objects stack (max 16MB). 
  1322. Returns current stack depth or ERROR.
  1323.  
  1324.  
  1325. long cfpop_value(
  1326.                 void *handle,  // an open object
  1327.                 unsigned long *valptr
  1328.                )
  1329. Pops an unsigned long integer from the top of the objects stack.
  1330.  
  1331. long cfpop_item(
  1332.                 void *handle,  // an open object
  1333.                 void *itemptr
  1334.                )
  1335. Pops an item from the top of the objects stack.
  1336. IF THE ITEM DESCRIBES DATA, THE DATA HAS NOT BEEN DELETED (use cfretspace()).
  1337. I have chosen this dangerous method of dealing with the stack because
  1338. it can be very useful. i.e. One part of a program can push a lot of data
  1339. without regard for where it is going or assigning a key to it, another
  1340. part of a program can pop the items which describe the data and save the
  1341. items for later keyed retrieval, the data moves once. This method is doubly
  1342. dangerous: First, the programmer must ensure that the data can eventually
  1343. be deleted and Second, if a hashed object contains PREALLOCATED ENTRIES
  1344. then the data should NEVER be deleted because the preallocation mechanism
  1345. will want to reuse the space, and indeed will overwrite the data at some
  1346. time in the future.
  1347. Returns current stack depth or ERROR.
  1348.  
  1349.  
  1350. long cfpop_data(
  1351.                 void *handle,  // an open object
  1352.                 void *datbufptr,
  1353.                 int   datbuflen
  1354.                )
  1355. Pops data (if it exists) from the top of the stack.
  1356. If the top of the stack contains an item that does not describe data
  1357. the item is lost.
  1358. Returns current stack depth or ERROR.
  1359.  
  1360.  
  1361. long cfstackdepth(
  1362.                   void *handle  // an open object
  1363.                  )
  1364. Returns current stack depth or ERROR.
  1365.  
  1366.  
  1367.  
  1368. SPACE ALLOCATION
  1369.  
  1370. void *cfgetspace(
  1371.                   void *handle,  // an open object
  1372.                   long  amount,  // max 16MB
  1373.                   void *itemptr     // receives an Item which describes the space
  1374.                 )
  1375. Returns 'itemptr' if success or NULL.
  1376.  
  1377.  
  1378. int cfretspace(
  1379.                 void *handle,  // an open object
  1380.                 void *itemptr  // pointer to an Item which describes space
  1381.               )
  1382. Returns OK or ERROR
  1383. CFF Version 5.9 will abort if the Item does not describe valid space.
  1384. I think that this is better than returning an error.
  1385.  
  1386.  
  1387.     MEMORY FUNCTIONS
  1388.     void *malloc(size_t)
  1389.     void *calloc(unsigned, unsigned)
  1390.     void *realloc(void *, unsigned)
  1391.     void *valloc(unsigned)
  1392.     void *memalign(unsigned, unsigned)
  1393.     void free(void *)
  1394.     unsigned mallocsize(void *)
  1395.     void *cfmalloc(unsigned, Item *)
  1396.     void cffree(Item *)
  1397.  
  1398.     MEMORY BY CATEGORY FUNCTIONS
  1399.     void *mallocC(long, unsigned)
  1400.     void *callocC(long, unsigned, unsigned)
  1401.     void *reallocC(long, unsigned, unsigned)
  1402.     void *vallocC(long, unsigned)
  1403.     void *memalignC(long, unsigned, unsigned)
  1404.     void freeC(long, void *)
  1405.     void freecat(long)
  1406.  
  1407. CONTROL FUNCTIONS
  1408.  
  1409. long cfmodbufs(
  1410.                 long increment   // positive or negative increment in K bytes
  1411.               )
  1412. Changes the allowed buffering space by 'increment'.
  1413. Returns OK
  1414.  
  1415. long cfsetlazy(
  1416.                void *handle        // an open object
  1417.               )
  1418. Changes the writethrough characteristic of the object to LAZY.
  1419. Some bookeeping entries are forced out.
  1420. Returns OK or ERROR
  1421.  
  1422. long cfsetverylazy(
  1423.                    void *handle  // an open object
  1424.                   )
  1425. Changes the writethrough characteristic of the object to VERYLAZY.
  1426. No data is forced out.
  1427. Returns OK or ERROR
  1428.  
  1429. long cfclrlazy(
  1430.                void *handle   // an open object
  1431.               )
  1432. Sets the writethrough characteristic of the object to NORMAL.
  1433. Forces out everything.
  1434. Returns OK or ERROR
  1435.  
  1436. long cfsetkeycmp(
  1437.                  void *handle,                          // open object
  1438.                  int (*func)(void *, int, void *, int)  // function pointer
  1439.                 )
  1440. Changes the default key comparison routine for an object to a programmer
  1441. supplied version.
  1442. Returns OK or ERROR
  1443.  
  1444. long cfsetitemcmp(
  1445.                  void *handle,                // open object
  1446.                  int (*func)(void *, void *)  // function pointer
  1447.                 )
  1448. Changes the default item comparison routine for an object to a programmer
  1449. supplied version.
  1450. Returns OK or ERROR
  1451.  
  1452. long cfsetprintfunc(
  1453.                  int (*func)(int)  // function pointer
  1454.                 )
  1455. Changes the default system print function to a programmer supplied version.
  1456. The function must print one character at a time,
  1457. and return 1 for success, -1 for error.
  1458. Returns OK
  1459.  
  1460. void cfport_settestflags(
  1461.                          int flags
  1462.                         )
  1463. Set flags in the portability module 'cfport.c'. This command is issued
  1464. before cfinit(). The only defined flag is 1, which causes the extended
  1465. memory driver to enable a 4Meg local buffer for testing purposes.
  1466. If the 1 flag is not set, the system will map extended memory to
  1467. primary memory unless the programmer has included a 'real' extended
  1468. memory driver in cfport.c
  1469.  
  1470.  
  1471. COPY OBJECTS, FILESYSTEMS and FILES
  1472.  
  1473. void *cfcopy(
  1474.              void *something_dst,  // designates the destination
  1475.              void *something_src   // designates the source
  1476.             )
  1477.  
  1478. Copy the source to the destination.
  1479. The arguments can be paths or handles.
  1480. The source may be an object, a filesystem or an external file.
  1481. Ditto for the destination.
  1482. Sorted objects (created with F_SORTED) may not be copied to a filesystem.
  1483. If the source or destination is an external file, then the file property
  1484. of the object is copied.
  1485.  
  1486. Returns a handle to the OPENED destination or NULL.
  1487. NOTE: If the destination argument was an open handle, then the returned
  1488. handle SUPERCEEDS the original. i.e. the open object was deleted and
  1489. recreated.
  1490.  
  1491.  
  1492. DIRECT ACCESS TO DATA IN THE BUFFERS
  1493.  
  1494. void *cflocalize(
  1495.                  void *handle,   // an open object
  1496.                  void *item      // pointer to an Item which describes space
  1497.                 )
  1498. Returns a pointer to memory or NULL.
  1499. This command ties up one buffer header.
  1500. Be certain to release the buffer when finished.
  1501. The buffers are in the heap and thus are not memory protected.
  1502.  
  1503.  
  1504. void cfrelease(
  1505.                void *memptr,  // a pointer to memory returned by cflocalize()
  1506.                long  relmode  // R_CLEAN, R_DIRTY, R_FLUSH
  1507.               )
  1508. Release a buffer. 
  1509. If the release mode is R_CLEAN, then the buffer may never be written out.
  1510. If the release mode is R_DIRTY, then the buffer will eventually be written out.
  1511. If the release mode is R_FLUSH, then the buffer is written out immediately if
  1512. the object writethrough condition is not VERYLAZY. If the object may be in
  1513. VERYLAZY mode, be sure to use (R_DIRTY|R_FLUSH).
  1514.  
  1515.  
  1516. NAME TRANSLATION FUNCTIONS
  1517.  
  1518. int cfdef(
  1519.           char *keyptr,  // the key for the definition string
  1520.           char *defptr  // the definition string, entered in local dictionary
  1521.          )
  1522. Enters the definition string in the local dictionary, under the key.
  1523. Local definitions override application and system definitions.
  1524. Returns OK or ERROR
  1525.  
  1526.  
  1527. int cfundef(
  1528.             char *keyptr   // the key to a definition string
  1529.            )
  1530. Deletes a definition string from the local dictionary.
  1531. returns OK or ERROR
  1532.  
  1533.  
  1534. int cfsysdef(
  1535.               char *keyptr,  // the key for the definition string
  1536.               char *defptr  // the definition string, entered in PERMFILE
  1537.              )
  1538. Enters the definition string in the permanent system dictionary (if it exists).
  1539. PERMFILE is enabled if arg 3 of cfinit() mentions a valid '.cff' file.
  1540. Returns OK or ERROR
  1541.  
  1542.  
  1543. int cfsysundef(
  1544.                char *keyptr  // the key to a defined string
  1545.                )
  1546. Deletes a definition string from the permanent system dictionary.
  1547. Returns OK or ERROR
  1548.  
  1549. int cfappdef(
  1550.               char *keyptr,  // the key for the definition string
  1551.               char *defptr  // the definition string, entered in PERMINFO
  1552.              )
  1553. Enters the definition string in the permanent application dictionary.
  1554. Application definitions override system definitions.
  1555. PERMINFO is enabled if arg 3 of cfinit() mentions a valid '.cff' file.
  1556. Returns OK or ERROR
  1557.  
  1558.  
  1559. int cfappundef(
  1560.                char *keyptr  // the key to a defined string
  1561.                )
  1562. Deletes a definition string from the permanent application dictionary.
  1563. Returns OK or ERROR
  1564.  
  1565.  
  1566. int cftrn(
  1567.           char *input_string,
  1568.           char **output_string
  1569.          )
  1570. Translates the input string to the output string using the dictionaries.
  1571. The programmer must free the output string.
  1572. Returns OK or ERROR
  1573.  
  1574.  
  1575. int cfpathtrn(
  1576.               char *input_string,
  1577.               char **output_string
  1578.              )
  1579. Translates the input string to a fully qualified path, using the dictionaries
  1580. and the current working directory.
  1581. The programmer must free the output string.
  1582. Returns 0 if internal object, 1 if external file, 2 if filesys, 3 if rawdevice
  1583. Returns ERROR if trouble.
  1584.  
  1585.  
  1586. int cfchdir(
  1587.             char *newpath
  1588.            )
  1589. Change the current working directory.
  1590. Returns OK or ERROR
  1591.  
  1592.  
  1593. NOTE: to get the current working directory:
  1594. {
  1595. char *cwd;
  1596.     cfpathtrn(".", &cwd);
  1597.     
  1598.     ...
  1599.     
  1600.    free(cwd);
  1601. }
  1602. NOTE: CFF does not include disk drive prefixes in the cwd, the programmer
  1603.       may include them when opening a file or filesystem.
  1604.  
  1605. NOTE: The translator works mostly on the left hand side of a path;
  1606.       it first tries to translate the whole input string, then it expands
  1607.       the left hand side up to 10 times, then it tries to translate the
  1608.       whole result string. Would a macro facility be helpful?
  1609.  
  1610.  
  1611. STREAM I/O
  1612.  
  1613.       The standard flavors of opening stream files are supported.
  1614.       There are several new modes for opening and reopening files.
  1615.  
  1616.         Mode    Meaning
  1617.         "x"     Open a string, (put the string in place of the filename)
  1618.         "U"     Create a unique file, (supply a directory path as the filename)
  1619.         "T"     Open a temporary file, deleted on close.
  1620.         "M"     Open a file in memory.
  1621.         "s"        Open a file in 'stat' mode, i.e. parents are also readonly.
  1622.         "t"        Open file in 'text' mode, default is binary.
  1623.         "b"        Open file in binary mode, default (to be msdos compatible).
  1624.  
  1625.     As with cfopen, the stream handlers can open chunks and values for reading.
  1626.  
  1627. /* STDIO STUFF */
  1628. #define __BUFSIZ_  512
  1629.  
  1630. extern  struct  cf_iobuf {
  1631.     int      _cnt;
  1632.     char*    _ptr;
  1633.     char*    _base;
  1634.     int      _bufsiz;
  1635.     int      _flag;
  1636.     void *   _file;    // cff handle
  1637.     char     _sbuf;
  1638. } cf_iob[];
  1639.  
  1640. typedef struct cf_iobuf cfFILE;
  1641.  
  1642. #define cf_IOFBF    00000
  1643. #define cf_IOREAD   00001
  1644. #define cf_IOWRT    00002
  1645. #define cf_IONBF    00004
  1646. #define cf_IOMYBUF  00010
  1647. #define cf_IOEOF    00020
  1648. #define cf_IOERR    00040
  1649. #define cf_IOSTRG   00100
  1650. #define cf_IOLBF    00200
  1651. #define cf_IORW     00400
  1652. #define cf_IOAPPEND 01000
  1653. #define cf_IOTEXT   02000  /* for MSDOS cr/lf style files */
  1654.  
  1655. #define cfstdin     (&cf_iob[0])
  1656. #define cfstdout    (&cf_iob[1])
  1657. #define cfstderr    (&cf_iob[2])
  1658. #define cfstdaux    (&cf_iob[3])
  1659. #define cfstdprn    (&cf_iob[4])
  1660.  
  1661. #define cfgetc(p) (--(p)->_cnt>=0 ? \
  1662. (int)(*(unsigned char*)(p)->_ptr++) : \
  1663. cf_filbuf(p))
  1664. #define cfputc(x,p) (--(p)->_cnt>=0? \
  1665. ((int)((unsigned char)((*(p)->_ptr++=(unsigned)(x))))): \
  1666. cf_flsbuf((unsigned)(x),p))
  1667.  
  1668. #define cfclearerr(p) ((p)->_flag &= ~(cf_IOERR|cf_IOEOF))
  1669. #define cfgetchar()   cfgetc(cfstdin)
  1670. #define cfputchar(x)  cfputc(x,cfstdout)
  1671. #define cffeof(p)     (((p)->_flag&cf_IOEOF)!=0)
  1672. #define cfferror(p)   (((p)->_flag&cf_IOERR)!=0)
  1673. #define cffileno(p)   (cf_filelist[(p)->_file])
  1674.  
  1675. cfFILE*  cffopen(char *something, char *mode);
  1676. cfFILE*  cffreopen(char *something, char *mode, cfFILE *iop);
  1677. cfFILE*  cffdopen(void *handle, char *mode);
  1678. int      cf_filbuf(cfFILE*);
  1679. int      cf_flsbuf(unsigned, cfFILE*);
  1680. int      cffclose(cfFILE*);
  1681. int      cffflush(cfFILE*);
  1682. int      cffgetc(cfFILE*);
  1683. char*    cffgets(char*, int, cfFILE *);
  1684. int      cffputc(int, cfFILE*);
  1685. int      cffputs(char*, cfFILE*);
  1686. int      cffread(void*, int, int, cfFILE*);
  1687. int      cffseek(cfFILE*, long, int);
  1688. long     cfftell(cfFILE *);
  1689. int      cfsetpos(cfFILE *, long *);
  1690. int      cfgetpos(cfFILE *, long *);
  1691. cfFILE   *cftmpfile(void);
  1692. char     *cftmpnam(char *buf);
  1693. char     *cftempnam(char *dir, char *pref);
  1694. int      cffwrite(void*, int, int, cfFILE*);
  1695. char*    cfgets(char*);
  1696. int      cfgetw(cfFILE*);
  1697. int      cfputs(char*);
  1698. int      cfputw(int, cfFILE*);
  1699. void     cfrewind(cfFILE*);
  1700. int      cfsetbuf(cfFILE*, char*);
  1701. int      cfsetbuffer(cfFILE*, char*, int);
  1702. int      cfsetlinebuf(cfFILE*);
  1703. int      cfsetvbuf(cfFILE*, char*, int, int);
  1704. int      cfungetc(int, cfFILE*);
  1705.  
  1706. int      cfprintf(const char *fmt, ...);
  1707. int      cfeprintf(const char *fmt, ...);
  1708. int      cffprintf(cfFILE *iop, const char *fmt, ...);
  1709. int      cfsprintf(char *str, const char *fmt, ...);
  1710. int      cfvprintf(void *fmt, ...);
  1711. int      cfvfprintf(cfFILE *iop, const char *fmt, ...);
  1712. int      cfvsprintf(char *str, const char *fmt, ...);
  1713.  
  1714. int cfsscanf(char *str, const char *fmt, ...);
  1715. int cffscanf(cfFILE *iop, const char *fmt, ...);
  1716. int cfscanf(const char *fmt, ...);
  1717.  
  1718.  
  1719. DATA COMPRESSION
  1720.  
  1721. int cfzip(
  1722.           void *something_dst, // path, handle or memory address
  1723.           int dstsize,  // if non zero the size of destination MEMORY buf
  1724.           void *something_src, // path, handle or memory address
  1725.           int srcsize,  // if non zero the size of the source MEMORY buf
  1726.           )
  1727. If something_dst is NULL, then no output is generated. Use to get final size.
  1728. Returns compressed size or ERROR.
  1729.  
  1730. NOTE: If nonzero, srcsize and dstsize imply that a memory address is in
  1731.       the something_dst or something_src arg.
  1732.  
  1733.  
  1734. int cfunzip(
  1735.           void *something_dst, // path, handle or memory address
  1736.           int dstsize,  // if non zero the size of destination MEMORY buf
  1737.           void *something_src, // path, handle or memory address
  1738.           int srcsize  // if non zero the size of the source MEMORY buf
  1739.           )
  1740. If something_dst is NULL, then no output is generated. Use to get final size.
  1741. Returns uncompressed size or ERROR.
  1742.  
  1743. NOTE: If nonzero, srcsize and dstsize imply that a memory address is in
  1744.       the something_dst or something_src arg.
  1745.  
  1746.  
  1747. INFORMATIONAL FUNCTIONS
  1748.  
  1749. int cflastdupname(
  1750.                   void *handle,
  1751.                   void *keyptr,
  1752.                   int   keylen,
  1753.                   DupName *dupname  // filled if successful
  1754.                  )
  1755. If DupNames exist for the key, 'dupname' is filled with the last one.
  1756. Returns OK or ERROR
  1757.  
  1758. long cfcountdups(
  1759.                  void *handle,
  1760.                  void *keyptr,
  1761.                  int   keylen
  1762.                 )
  1763. Returns the actual duplicate count for a key. If DupNames are being used
  1764. then the actual count is the last DupName minus the number of prior deletions.
  1765. Each DupName key has a deletion counter which is incremented for every
  1766. successful delete except cfdelete_lastdupname().
  1767. Normal duplicates are just overtly scanned and counted.
  1768.  
  1769. int cfstat(
  1770.            void *something, // a handle or a path
  1771.            void *stbuf      // pointer to a CFSTAT struct
  1772.           )
  1773. returns OK or ERROR
  1774.  
  1775. int cfsubstat(
  1776.             void *handle,    // only a handle
  1777.             char *name,        // name of element, a chunk or node
  1778.             void *stbuf        // pointer to a CFSTAT struct
  1779.             )
  1780. returns OK or ERROR
  1781. If element is a chunk then OB_CHUNK and M_CHUNK are set and
  1782. st_filesize = st_filealloc = size of the chunk. The rest of the stat
  1783. info refers to the parent of the element.
  1784.  
  1785. typedef struct cffstat {
  1786.         unsigned long   st_smhead;
  1787.         unsigned long   st_smtail;
  1788.         unsigned short  st_id;
  1789.         unsigned short  st_keysize;
  1790.  
  1791.         STOR           st_dups;
  1792.         unsigned long  st_bmhead;
  1793.         unsigned long  st_bmtail;
  1794.         unsigned long  st_mode;
  1795.         short          st_uid;
  1796.         short          st_gid;
  1797.         long           st_mtime;
  1798.         long           st_ctime;
  1799.  
  1800.         unsigned long  st_highleaf;
  1801.         unsigned long  st_size;
  1802.         unsigned long  st_alloc;
  1803.         unsigned long  st_entrycnt;
  1804.         short          st_mapsize;
  1805.         unsigned short st_dupids;
  1806.  
  1807.         long           st_atime;
  1808.         long           st_filesize;
  1809.         long           st_filealloc;
  1810.         long           st_obtype;
  1811.         unsigned int   st_filedups;
  1812.         long           st_ino;
  1813.         short          st_blksize;
  1814.         short          st_dev;
  1815.         short          st_nlink;
  1816.         short          st_rdev;
  1817. } CFSTAT;
  1818.  
  1819.  
  1820.  
  1821.  
  1822.  
  1823. /* MODE BITS in st_mode */
  1824. #define M_ROOTDIR   0x80000000
  1825. #define M_FILEONLY  0x40000000
  1826. #define M_HASHDIR   0x20000000
  1827. #define M_TREEDIR   0x10000000
  1828. #define M_UNTAGGED  0x08000000
  1829. #define M_BITMAP    0x04000000
  1830. #define M_EXTRNFILE 0x02000000
  1831. #define M_PREALLOC  0x01000000
  1832. #define M_ZIPFILE    0x00800000
  1833. #define M_ZIPDATA    0x00400000
  1834. #define M_CHUNK        0x00200000
  1835. #define M_IFMT      0x000F0000
  1836. #define M_IFDIR     0x00004000
  1837. #define M_IFIFO     0x00002000
  1838. #define M_IFCHR     0x00001000
  1839. #define M_IFBLK     0x00003000
  1840. #define M_IFREG     0x00008000
  1841. #define M_IREAD     0x00000100
  1842. #define M_IWRITE    0x00000080
  1843. #define M_IEXEC     0x00000040
  1844.  
  1845.  
  1846. long cfentrycnt(
  1847.                 void *something
  1848.                )
  1849. returns the entrycount of a handle or a path, or ERROR
  1850.  
  1851.  
  1852. long cfdepth(
  1853.              void *handle
  1854.             )
  1855. returns treedepth or ERROR
  1856.  
  1857.  
  1858. long cfbytesused(
  1859.                  void *handle
  1860.                 )
  1861. returns the bytes used in the object or ERROR
  1862.  
  1863.  
  1864. long cfbytesalloc(
  1865.                   void *handle
  1866.                  )
  1867. returns the bytes allocated to the object or ERROR
  1868.  
  1869.  
  1870. long cftotalloc(
  1871.                 void *something,
  1872.                 unsigned long *used,
  1873.                 unsigned long *alloc
  1874.                )
  1875. returns OK if something exists, sets used and alloc to the total space
  1876. allocated to the object and all of it's subobjects in 1000's of bytes.
  1877.  
  1878.  
  1879. long cfstackdepth(
  1880.                   void *handle
  1881.                  )
  1882. returns the current stackdepth of the object or ERROR
  1883.  
  1884.  
  1885. long cfcurbufs(
  1886.                void
  1887.               )
  1888. returns the current allowed localizer buffer space in K bytes.
  1889.  
  1890.  
  1891. long cfisnew(
  1892.              void *handle
  1893.             )
  1894. returns 1 if object is newly created, 0 if not, ERROR if invalid handle
  1895.  
  1896.  
  1897. long cffilesize(
  1898.                 void *handle
  1899.                )
  1900. returns the size of the file property of the object or ERROR
  1901.  
  1902.  
  1903. long cffilealloc(
  1904.                  void *handle
  1905.                 )
  1906. returns the space allocated to the file property or ERROR
  1907.  
  1908.  
  1909. long cfprealloc(
  1910.                 void *handle
  1911.                )
  1912. returns the size of each preallocated chunk or 0 or ERROR
  1913.  
  1914.  
  1915. long cfmapsize(
  1916.                void *handle
  1917.               )
  1918. returns the node size of the object or ERROR
  1919.  
  1920.  
  1921. long cfalignment(
  1922.                  void *handle
  1923.                 )
  1924. returns the alignment for the object (32 is hardwired in version 5.9)
  1925.  
  1926.  
  1927. long cfissorted(
  1928.                 void *handle
  1929.                )
  1930. returns 1 if the object is sorted, 0 if not or ERROR
  1931.  
  1932.  
  1933. void cfprintbitmaps(
  1934.                     void *something  // a path or handle
  1935.                    )
  1936. Prints the bitmaps for the target object and it's parents.
  1937.  
  1938.  
  1939. void cfprintentries(
  1940.                     void *something  // a path or handle
  1941.                    )
  1942. Prints all the entries in the target object's nodes.
  1943.  
  1944. long cfhash(
  1945.             void *keyptr,
  1946.             int   keylen,
  1947.             CAT  *cat    // pointer to a CAT structure
  1948.            )
  1949. Calls the system hash function for the supplied key. The CAT structure
  1950. receives the hashed output. Useful for generating random numbers etc.
  1951. Returns OK.
  1952.    
  1953.  
  1954. void cfmemrange(
  1955.                 long category,
  1956.                 unsigned long *min,
  1957.                 unsigned long *max
  1958.                 )
  1959. Fills in min and max for the category, 0 for unallocated categories.
  1960.  
  1961. void cftotrange(
  1962.                 unsigned long *min,
  1963.                 unsigned long *max
  1964.                 )
  1965. Fills in min and max for all memory allocated.
  1966.  
  1967. long cfobtype(
  1968.               void *something
  1969.              )
  1970. returns the OB bits or ERROR
  1971.  
  1972. #define OB_SHARE    0x00000001  // object can be opened more than once
  1973. #define OB_ISDIR    0x00000002  // object is a directory
  1974. #define OB_BMOK     0x00000004  // bitmaps loaded
  1975. #define OB_SMOK     0x00000008  // storage maps loaded
  1976. #define OB_MEM      0x00000010  // memory object
  1977. #define OB_RAWDEV   0x00000020  // raw device
  1978. #define OB_CFILE    0x00000040  // part of a disk filesys
  1979. #define OB_SETUP    0x00000080  // object is setup
  1980. #define OB_FOD      0x00000100  // on a file oriented device
  1981. #define OB_ROOTDIR  0x00000200  // object is the root directory
  1982. #define OB_DIRTY    0x00000400  // has been written to
  1983. #define OB_DELCLOSE 0x00000800  // delete on close
  1984. #define OB_WRITE    0x00001000  // ok to write to this object
  1985. #define OB_BITMAP   0x00002000  // has a bitmap
  1986. #define OB_XFILE    0x00004000  // is an external OS file
  1987. #define OB_ISNEW    0x00008000  // newly created
  1988. #define OB_SMEM     0x00010000  // extended memory object
  1989. #define OB_FILEONLY 0x40000000  // created with F_FILEONLY
  1990. #define OB_HASHDIR  0x20000000  // uses hashed maps
  1991. #define OB_TREEDIR  0x10000000  // uses B+ tree maps
  1992. #define OB_UNTAGGED 0x08000000  // contains untagged items
  1993. #define OB_PREALLOC 0x01000000  // contains prealloced data and entries
  1994. #define OB_ZIPFILE    0x00800000    // file aspect is compressed
  1995. #define OB_ZIPDATA    0x00400000  // data chunks are compressed
  1996. #define OB_CHUNK    0x00200000    // object is a data chunk or value
  1997.  
  1998.  
  1999.  
  2000.